import UI_Scene from "../../ui/Main/UI_Scene";
import BaseUIMediator from "../../LTGame/UI/BaseUIMediator";
import UI_HierarchyMediator from "./UI_HierarchyMediator";
import UI_InspectorMediator from "./UI_InspectorMediator";
import { EventCenter } from "../../LTGame/Event/EventCenter";
import { EventIDs } from "../common/EventIds";
import { DebuggerManager } from "../debugger/DebuggerManager";
import { TransPack } from "../../server/framework/common/TransPack";
import { EMessageC2C } from "../../common/EMessageC2C";
import { QueryImgBack } from "../debug_inject/handler/HandleQuerySceneImg";
import MonoHelper, { EActionType } from "../../LTGame/Utils/MonoHelper";
import { ViewStatus } from "./view/ViewStatus";
import { ViewRightMouse } from "./view/ViewRightMouse";
import { LTInput } from "../../LTGame/Event/LTInput";
import { EKeyCode } from "../../LTGame/Event/EKeyCode";
import { UInt8ArrayEx } from "../../LTGame/Utils/UInt8ArrayEx";

export default class UI_SceneMediator extends BaseUIMediator<UI_Scene> {

    private static _instance: UI_SceneMediator;
    public static get instance(): UI_SceneMediator {
        if (this._instance == null) {
            this._instance = new UI_SceneMediator();
            this._instance._classDefine = UI_Scene;
        }
        return this._instance;
    }

    private _selectObjId: number;

    private _cacheImage: fgui.GImage;
    private _texture2d: Laya.Texture2D;

    private _isForce: boolean;

    private _viewStatus: ViewStatus;
    private _waitTime: number;

    private _viewRightMouse: ViewRightMouse;

    private _cacheSize: Laya.Vector2;

    private _isMouseIn: boolean;

    private _needTrans: boolean;

    _OnShow() {
        super._OnShow();
        // your code

        this._needTrans = true;
        this._isForce = true;
        this._waitTime = 0;

        let x = UI_HierarchyMediator.instance.ui.x + UI_HierarchyMediator.instance.ui.width + 10;
        this.ui.setXY(x, 10);
        let width = UI_InspectorMediator.instance.ui.x - 10 - x;
        this.ui.setSize(width, this.ui.parent.height - 20);

        this.ui.m_toggle_trans.m_state_check.selectedIndex = this._needTrans ? 1 : 0;

        this._viewStatus = new ViewStatus(this.ui.m_view_status);
        this._viewRightMouse = new ViewRightMouse(this.ui);

        this.ui.m_btn_reset.onClick(this, this._OnClickResetCamera);
        this.ui.m_toggle_trans.onClick(this, this._OnClickTrans);

        this._cacheImage = new fgui.GImage();
        this._cacheImage.width = this.ui.m_img_display.width;
        this._cacheImage.height = this.ui.m_img_display.height;
        this.ui.addChild(this._cacheImage);
        this._cacheImage.setXY(this.ui.m_img_display.x, this.ui.m_img_display.y);
        this.ui.m_img_display.visible = false;
        this._cacheImage.visible = false;
        const scale = 1 / 2;
        this._cacheSize = new Laya.Vector2(Math.floor(this._cacheImage.width * scale), Math.floor(this._cacheImage.height * scale));
        this._texture2d = new Laya.Texture2D(this._cacheSize.x, this._cacheSize.y, Laya.TextureFormat.R8G8B8A8, false, true);
        this._cacheImage.image.texture = new Laya.Texture(this._texture2d);

        EventCenter.instance.Regist(EventIDs.SelectObj, this, this._OnSelectObj);
        DebuggerManager.instance.RegistClientMsg(EMessageC2C.QuerySceneImg_Back, this, this._OnMsgBack);
        MonoHelper.instance.AddAction(EActionType.Update, this, this._LogicUpdate);
    }

    _OnHide() {
        this._viewRightMouse.Dispose();

        MonoHelper.instance.RemoveAction(EActionType.Update, this, this._LogicUpdate);
        EventCenter.instance.UnRegist(EventIDs.SelectObj, this, this._OnSelectObj);
        DebuggerManager.instance.UnRegistClientMsg(EMessageC2C.QuerySceneImg_Back);
    }

    private _OnClickTrans() {
        this._needTrans = !this._needTrans;
        this.ui.m_toggle_trans.m_state_check.selectedIndex = this._needTrans ? 1 : 0;
    }

    private _OnClickResetCamera() {
        DebuggerManager.instance.ResetSceneCameraPos();
    }

    private _LogicUpdate(dt: number) {
        if (this._selectObjId == null) return;

        // 位置
        if (this._viewRightMouse.isPressed) {
            let cacheX: number = 0;
            let cacheZ: number = 0;
            if (LTInput.instance.GetKey(EKeyCode.Key_W)) {
                cacheZ += 1;
            }
            if (LTInput.instance.GetKey(EKeyCode.Key_A)) {
                cacheX += 1;
            }
            if (LTInput.instance.GetKey(EKeyCode.Key_S)) {
                cacheZ -= 1;
            }
            if (LTInput.instance.GetKey(EKeyCode.Key_D)) {
                cacheX -= 1;
            }
            DebuggerManager.instance.SetSceneCameraPos(-cacheX / 10, -cacheZ / 10);
        }

        // 旋转
        if (this._viewRightMouse.isPressed) {
            this._viewRightMouse.LogicUpdate();
            if (this._viewRightMouse.isDrag) {
                DebuggerManager.instance.SetSceneCameraRot(-this._viewRightMouse.dragVec.y / 10, -this._viewRightMouse.dragVec.x / 10);
            }
        }

        // 查询
        if (!this._viewStatus.isQuery) {
            this._waitTime -= dt;
            if (this._waitTime < 0) {
                this._waitTime = 0.05;
                this._QueryImage();
            }
        }
    }

    private _OnMsgBack(pack: TransPack) {
        this._viewStatus.isQuery = false;
        let recvData = pack.data as QueryImgBack;
        if (recvData.code == -1) {
            this._cacheImage.visible = false;
            return;
        }
        this._cacheImage.visible = true;
        if (recvData.code == 1) {
            // 与上一帧相同
            return;
        }
        this._isForce = false;
        this._AsyncSetImg(recvData.binImg);
    }

    private async _AsyncSetImg(binaryArray: Uint8Array) {
        this._texture2d.setPixels(binaryArray);
    }

    private _OnSelectObj(objIds: number[]) {
        if (objIds.length > 1) {
            console.error("暂时不支持多obj选择");
            return;
        }
        this.SelectObj(objIds[0]);
    }

    public SelectObj(objId: number) {
        if (this._selectObjId == objId) return;
        this._selectObjId = objId;
        if (this._selectObjId == null) {
            this._cacheImage.visible = false;
            return;
        }
        this._QueryImage();
    }

    private _QueryImage() {
        if (!this._needTrans) {
            this.ui.m_view_status.m_text_status.text = '已暂停';
            return;
        }
        this._viewStatus.isQuery = true;
        DebuggerManager.instance.QuerySceneImg(this._selectObjId,
            this._cacheSize.x, this._cacheSize.y, this._isForce);
    }

    private _Base64ToBlob(base64Data: string): Blob {
        let byteString: string;
        if (base64Data.split(",")[0].indexOf("base64") >= 0) {
            byteString = atob(base64Data.split(",")[1]);
        } else {
            byteString = Laya.Browser.window.unescape(base64Data.split(",")[1]);
        }
        let mimeString = base64Data.split(",")[0].split(":")[1].split(";")[0];
        let ia = new Uint8Array(byteString.length);
        for (var i = 0; i < byteString.length; i++) {
            ia[i] = byteString.charCodeAt(i);
        }
        return new Laya.Browser.window.Blob([ia], {
            type: mimeString
        });
    }

}